home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1997 / MacHack 1997.toast / Hacks / Hacks ’96 / TrimScreen / TrimScreen.c < prev    next >
C/C++ Source or Header  |  1996-06-21  |  3KB  |  92 lines

  1. #include <Palettes.h>
  2. #include <LoMem.h>
  3.  
  4. #include <StuTypes.h>
  5.  
  6. #pragma parameter __A0 RegA5()    // MOVEA.L A5,A0
  7. local Handle RegA5(void) = { 0x204D };
  8.  
  9. typedef struct { short number; Rect r[]; } nrct;
  10. typedef struct { Ptr baseAddr; short rowBytes; long topleft; long botright; } BMTemplate;
  11.  
  12. void fix_bitmap(BitMap *bm, Ptr newbase, short newright);
  13. void fix_grafport(GrafPtr gp, Ptr newbase, short newright);
  14.  
  15. export void main(void)
  16.     {
  17.     QDGlobals *qdglobptr = (QDGlobals *)(*RegA5() - sizeof(QDGlobals) + sizeof(GrafPtr));
  18.     nrct **rh = (nrct **)GetResource('nrct', 0);        // Read configuration
  19.     GDPtr gdevp = GetMainDevice()[0];                    // Get the main screen device
  20.     PixMapPtr pm = gdevp->gdPMap[0];                    // And get its pixmap
  21.     // Decide what multiple to round pixel count to (to preserve byte alignment)
  22.     short pixel_mask = (pm->pixelSize >= 8) ? 0 : (8 / pm->pixelSize - 1);
  23.     // pixels cut from left edge
  24.     short trim_l = (rh[0]->r[0].left + pixel_mask) & ~pixel_mask;
  25.     short pixels_cut = trim_l + rh[0]->r[0].right;        // Total pixels cut
  26.     long byte_shift = trim_l * pm->pixelSize / 8;        // Offset to add to baseAddr
  27.     Ptr newbase    = pm->baseAddr + byte_shift;
  28.     short newright = pm->bounds.right - pixels_cut;
  29.     WindowPeek wp = WindowList;
  30.     register BMTemplate *bm = NULL;
  31.     register Ptr oldbase = pm->baseAddr;
  32.     register long oldtopleft  = *(long*)(&pm->bounds.top);
  33.     register long oldbotright = *(long*)(&pm->bounds.bottom);
  34.     
  35.     //Debugger();
  36.     ScrnBase = newbase;                                // Update the ScrnBase lomem variable
  37.     gdevp->gdRect.right = newright;                    // Fix the gdRect of the main device
  38.     CrsrPin.right = newright;                        // Update the cursor limit rect
  39.     
  40.     // If an A5 world is set up, fix the screenBits variable
  41.     if (qdglobptr->screenBits.baseAddr == pm->baseAddr)
  42.         fix_bitmap(&qdglobptr->screenBits, newbase, newright);
  43.     fix_bitmap((BitMap*)pm, newbase, newright);        // Fix the main device's pixmap
  44.     fix_grafport(WMgrPort, newbase, newright);        // Fix the window manager (desktop) ports
  45.     fix_grafport((GrafPtr)WMgrCPort, newbase, newright);
  46.     while (wp)                                        // Fix any open windows
  47.         {
  48.         fix_grafport(&wp->port, newbase, newright);
  49.         wp=wp->nextWindow;
  50.         }
  51.     
  52.     // Damn! After all this, it still doesn't work. Do an exhaustive search of all
  53.     // memory, finding all BitMaps which look like copies of screenBits, and fix them.
  54.     while ((Ptr)bm < BufPtr)
  55.         {
  56.         if (bm->baseAddr == oldbase &&
  57.             bm->topleft == oldtopleft &&
  58.             bm->botright == oldbotright)
  59.                 fix_bitmap((BitMap *)bm, newbase, newright);
  60.         bm = (BMTemplate*)((Ptr)bm+2);
  61.         }
  62.     
  63.     {
  64.     int i = 0;
  65.     long rowbytes = pm->rowBytes & 0x3FFF;
  66.     Ptr p = oldbase;
  67.     while (i<pm->bounds.bottom)
  68.         {
  69.         int j;
  70.         Ptr pp = p;
  71.         for (j=0; j<byte_shift; j++) *pp++ = 0xFF;
  72.         p += rowbytes;
  73.         i++;
  74.         }
  75.     }
  76.     
  77.     }
  78.  
  79. void fix_bitmap(BitMap *bm, Ptr newbase, short newright)
  80.     {
  81.     // Check if this is actually the PixMapHandle of a CGrafPort
  82.     if ((bm->rowBytes & 0xC000) == 0xC000) bm = (BitMap *)*(bm->baseAddr);
  83.     bm->baseAddr     = newbase;
  84.     bm->bounds.right = newright;
  85.     }
  86.  
  87. void fix_grafport(GrafPtr gp, Ptr newbase, short newright)
  88.     {
  89.     fix_bitmap(&gp->portBits, newbase, newright);
  90.     gp->portRect.right = newright;
  91.     }
  92.